home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / Xconq 7.0d16 / Xconq 7.0d16 src / mac / macimf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-03  |  8.0 KB  |  281 lines  |  [TEXT/KAHL]

  1. /* Copyright (c) 1992, 1993  Stanley T. Shebs. */
  2. /* This program may be used, copied, modified, and redistributed freely */
  3. /* for noncommercial purposes, so long as this notice remains intact. */
  4.  
  5. /* Handling for the Macintosh implementation of image families. */
  6.  
  7. /* Note! that this file does not use the standard "conq" header, so can't assume
  8.    the usual definitions. */
  9.  
  10. #ifdef THINK_C
  11. #include <MacHeaders>
  12. #else /* assume MPW */
  13. #include <Types.h>
  14. #include <Memory.h>
  15. #include <Resources.h>
  16. #include <Quickdraw.h>
  17. #endif /* THINK_C */
  18.  
  19. #include "::src:config.h"
  20. #include "::src:misc.h"
  21. #include "::src:lisp.h"
  22.  
  23. #include "macimf.h"
  24.  
  25. #define pascalify(STR, BUF) \
  26.   strcpy(((char *) BUF) + 1, STR);  \
  27.   BUF[0] = strlen(STR);
  28.  
  29. extern int hasColorQD;
  30.  
  31. char *copy_string();
  32.  
  33. /* Clear the entire image family. */
  34.  
  35. init_image_family(imf)
  36. ImageFamily *imf;
  37. {
  38.     int i, j;
  39.     Image *img;
  40.  
  41.     imf->name = NULL;
  42.     imf->ersatz = FALSE;
  43.     imf->numsizes = 0;
  44.     for (i = 0; i < MAXIMSIZES; ++i) {
  45.         img = &(imf->images[i]);
  46.         /* (should clear by just zeroing the block?) */
  47.         img->w = img->h = 0;
  48.         img->minw = img->minh = 0;
  49.         img->maxw = img->maxh = 0;
  50.         img->istile = 0;
  51.         img->embedname = NULL;
  52.         img->embedx = img->embedy = -1;
  53.         img->embedw = img->embedh = 0;
  54.         img->monosicn = img->masksicn = nil;
  55.         img->monoicon = img->colricon = img->maskicon = nil;
  56.         img->monopict = img->colrpict = img->maskpict = nil;
  57.         img->groupmonopict = img->groupcolrpict = img->groupmaskpict = nil;
  58.         img->groupmonox = img->groupmonoy = 0;
  59.         img->groupcolrx = img->groupcolry = 0;
  60.         img->groupmaskx = img->groupmasky = 0;
  61.         img->patdefined = 0;
  62.         for (j = 0; j < 8; ++j) img->pat[8] = '\0';
  63.         img->colrpat = nil;
  64.     }
  65. }
  66.  
  67. Image *
  68. get_img(imf, w, h)
  69. ImageFamily *imf;
  70. int w, h;
  71. {
  72.     int i;
  73.     Image *img;
  74.     
  75.     for (i = 0; i < imf->numsizes; ++i) {
  76.         img = &(imf->images[i]);
  77.         if (w == img->w && h == img->h) return img;
  78.     }
  79.     if (imf->numsizes >= MAXIMSIZES) return NULL;
  80.     img = &(imf->images[imf->numsizes]);
  81.     ++(imf->numsizes);
  82.     img->w = w;  img->h = h;
  83.     /* Default min/max limits to actual size. */
  84.     img->minw = w;  img->minh = h;
  85.     img->maxw = w;  img->maxh = h;
  86.     return img;
  87. }
  88.  
  89. /* This tries to fill in the given image family from various resources.  The order
  90.    should be "best first", so as to improve search time. */
  91.  
  92. load_image_family(imf)
  93. ImageFamily *imf;
  94. {
  95.     int w, h, i, rsize, startlineno, endlineno;
  96.     char tmpstrbuf[100], embeddedname[100];
  97.     Obj *imfspec;
  98.     Handle handle, imfhandle, pathandle, sicnhandle, iconhandle, maskhandle;
  99.     PicHandle pichandle;
  100.     PixPatHandle ppathandle;
  101.     CIconHandle cicnhandle;
  102.     Image *img;
  103.     Str255 namestr, maskstr, resname;
  104.     short resid;
  105.     ResType restype;
  106.  
  107.     /* Can't do anything without a name for the image family. */
  108.     if (imf->name == NULL) return;
  109.     pascalify(imf->name, namestr);
  110.     /* The name of the mask is always formed by appending " mask". */
  111.     sprintf(tmpstrbuf, "%s mask", imf->name);
  112.     pascalify(tmpstrbuf, maskstr);
  113.     if (imf->numsizes >= MAXIMSIZES) {
  114.         /* (should maybe mention about discarding images, but unlikely to happen ever. */
  115.         return;
  116.     }
  117.     embeddedname[0] = '\0';
  118.     /* Look for and load the "image family" specification resource first. */
  119.     if ((imfhandle = (Handle) GetNamedResource('XCif', namestr)) != nil) {
  120.         imfspec = read_form_from_string(copy_string(*imfhandle), &startlineno, &endlineno);
  121.         if (symbolp(imfspec)) {
  122.             strcpy(embeddedname, c_string(imfspec));
  123.         }
  124.     }
  125.     if ((pichandle = (PicHandle) GetNamedResource('PICT', namestr)) != nil) {
  126.         if ((img = get_img(imf, 16, 16) /* should get real bounds */) != NULL) {
  127.             img->minw = img->minh = 8;
  128.             img->maxw = img->maxh = 9999;
  129.             /* (should distinguish mono and color picts) */
  130.             img->monopict = pichandle;
  131.             /* Look for a mask too. */
  132.             if ((pichandle = (PicHandle) GetNamedResource('PICT', maskstr)) != nil) {
  133.                 img->maskpict = pichandle;
  134.             }
  135.             img->istile = 0;
  136.         }
  137.     }
  138.     /* (should also be able to pick up picts with rows and columns of images) */
  139.     /* Pick up cicns, if we're doing color. */
  140.     if (hasColorQD) {
  141.         if ((cicnhandle = (CIconHandle) GetNamedResource('cicn', namestr)) != nil) {
  142.             /* Need to get id so we can use special trap. */
  143.             GetResInfo((Handle) cicnhandle, &resid, &restype, &resname);
  144.             cicnhandle = GetCIcon(resid);
  145.             if ((img = get_img(imf, 32, 32)) != NULL) {
  146.                 img->minw = img->minh = 8;
  147.                 img->maxw = img->maxh = 128;
  148.                 img->colricon = (Handle) cicnhandle;
  149.                 /* Mask is built in, don't need to load separately. */
  150.             }
  151.         }
  152.     }
  153.     /* Pick up ICONs. */
  154.     if ((iconhandle = (Handle) GetNamedResource('ICON', namestr)) != nil) {
  155.         if ((img = get_img(imf, 32, 32)) != NULL) {
  156.             img->minw = img->minh = 8;
  157.             img->maxw = img->maxh = 128;
  158.             img->monoicon = iconhandle;
  159.             /* Look for a mask too. */
  160.             if ((iconhandle = (Handle) GetNamedResource('ICON', maskstr)) != nil) {
  161.                 img->maskicon = iconhandle;
  162.             }
  163.             img->istile = 0;
  164.         }
  165.     }
  166.     /* Pick up SICNs. */
  167.     if ((sicnhandle = (Handle) GetNamedResource('SICN', namestr)) != nil) {
  168.         if ((img = get_img(imf, 16, 16)) != NULL) {
  169.             img->minw = img->minh = 8;
  170.             img->maxw = img->maxh = 64;
  171.             /* Image itself is just the first 32 bytes, mask is second 32 if present. */
  172.             img->monosicn = sicnhandle;
  173.             rsize = SizeResource(sicnhandle);
  174.             if (rsize >= 64) {
  175.                 maskhandle = (Handle) NewHandle(32);
  176.                 for (i = 0; i < 32; ++i) {
  177.                     (*maskhandle)[i] = (*sicnhandle)[i+32];
  178.                 }
  179.                 img->masksicn = maskhandle;
  180.             } else {
  181.                 /* Mask could be separate resource, so look for it. */
  182.                 if ((iconhandle = GetNamedResource('SICN', maskstr)) != nil) {
  183.                     img->masksicn = sicnhandle;
  184.                 } else {
  185.                     /* no mask to be found */
  186.                 }
  187.             }
  188.             img->istile = 0;
  189.         }
  190.     }
  191.     /* Pick up color patterns, if we're capable of doing color. */
  192.     if (hasColorQD) {
  193.         if ((ppathandle = (PixPatHandle) GetNamedResource('ppat', namestr)) != nil) {
  194.             /* Need to get the id of the ppat so we can use special trap. */
  195.             GetResInfo((Handle) ppathandle, &resid, &restype, &resname);
  196.             ppathandle = GetPixPat(resid);
  197.             if ((img = get_img(imf, 8, 8)) != NULL) {
  198.                 /* Indicate that we can use this pattern for any size area. */
  199.                 img->minw = img->minh = 1;
  200.                 img->maxw = img->maxh = 9999;
  201.                 img->colrpat = ppathandle;
  202.                 img->istile = 1;
  203.             }
  204.         }
  205.     }
  206.     /* Load a pattern, which can be used for any size area, but whose "natural" size
  207.        is always 8x8. */
  208.     if ((pathandle = GetNamedResource('PAT ', namestr)) != nil) {
  209.         if ((img = get_img(imf, 8, 8)) != NULL) {
  210.             img->minw = img->minh = 1;
  211.             img->maxw = img->maxh = 9999;
  212.             for (i = 0; i < 8; ++i) {
  213.                 img->pat[i] = ((char *) *pathandle)[i];
  214.             }
  215.             img->patdefined = 1;
  216.             img->istile = 1;
  217.         }
  218.     }
  219.     if (strlen(embeddedname) > 0) {
  220.         for (i = 0; i < imf->numsizes; ++i) {
  221.             img = &(imf->images[i]);
  222.             img->embedname = copy_string(embeddedname);
  223.         }
  224.     }
  225. }
  226.  
  227. load_image_color(imc)
  228. ImageColor *imc;
  229. {
  230.     Handle imchandle;
  231.     Str255 namestr;
  232.  
  233.     if (imc->name == NULL) return;
  234.     pascalify(imc->name, namestr);
  235.     if ((imchandle = GetNamedResource('XCic', namestr)) != nil) {
  236.         imc->r = ((short *) (*imchandle))[0];
  237.         imc->g = ((short *) (*imchandle))[1];
  238.         imc->b = ((short *) (*imchandle))[2];
  239.     } else {
  240.         /* Not found. */
  241.         imc->r = imc->g = imc->b = 0;
  242.     }
  243. }
  244.  
  245. /* Try to find the best of multiple images for the given bounding box. */
  246. /* Don't return anything that won't fit in min space. */
  247.  
  248. Image *
  249. best_image(imf, w, h)
  250. ImageFamily *imf;
  251. int w, h;
  252. {
  253.     int i;
  254.     Image *img, *best = NULL, *fallback = NULL;
  255.     
  256.     for (i = 0; i < imf->numsizes; ++i) {
  257.         img = &(imf->images[i]);
  258.         /* Exact matches need no further searching. */
  259.         if (w == img->w && h == img->h && right_depth(img)) {
  260.             return img;
  261.         } else if (between(img->minw, w, img->maxw) && between(img->minh, h, img->maxh)) {
  262.             /* Image is plausible - go for the largest one that will fit. */
  263.             if (!best || (img->w > best->w && img->h > best->h)) {
  264.                 best = img;
  265.             }
  266.         } else if (w >= img->minw && h >= img->minh) {
  267.             /* Image is not really big enough, but keep as a fallback. */
  268.             if (!fallback || (img->w > fallback->w && img->h > fallback->h)) {
  269.                 fallback = img;
  270.             }
  271.         }
  272.     }
  273.     return (best ? best : fallback);
  274. }
  275.  
  276. right_depth(img)
  277. Image *img;
  278. {
  279.     return TRUE;
  280. }
  281.